"""
MySQL解析器测试
"""

import unittest
import tempfile
import os
from src.parser import MySQLParser, StatementType


class TestMySQLParser(unittest.TestCase):
    """MySQL解析器测试类"""
    
    def setUp(self):
        """测试前准备"""
        self.parser = MySQLParser()
    
    def test_parse_create_database(self):
        """测试CREATE DATABASE语句解析"""
        sql = "CREATE DATABASE IF NOT EXISTS test_db DEFAULT CHARSET=utf8;"
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.sql', delete=False) as f:
            f.write(sql)
            temp_file = f.name
        
        try:
            statements = self.parser.parse_file(temp_file)
            
            self.assertEqual(len(statements), 1)
            self.assertEqual(statements[0].statement_type, StatementType.CREATE_DATABASE)
            self.assertEqual(statements[0].database_name, 'test_db')
            
        finally:
            os.unlink(temp_file)
    
    def test_parse_create_table(self):
        """测试CREATE TABLE语句解析"""
        sql = """
        CREATE TABLE `users` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `name` varchar(100) NOT NULL,
            `email` varchar(255) DEFAULT NULL,
            `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            UNIQUE KEY `email_unique` (`email`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
        """
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.sql', delete=False) as f:
            f.write(sql)
            temp_file = f.name
        
        try:
            statements = self.parser.parse_file(temp_file)
            
            self.assertEqual(len(statements), 1)
            self.assertEqual(statements[0].statement_type, StatementType.CREATE_TABLE)
            self.assertEqual(statements[0].table_name, 'users')
            self.assertIsNotNone(statements[0].columns)
            self.assertTrue(len(statements[0].columns) > 0)
            
        finally:
            os.unlink(temp_file)
    
    def test_parse_insert_into(self):
        """测试INSERT INTO语句解析"""
        sql = "INSERT INTO `users` (`name`, `email`) VALUES ('John', 'john@example.com');"
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.sql', delete=False) as f:
            f.write(sql)
            temp_file = f.name
        
        try:
            statements = self.parser.parse_file(temp_file)
            
            self.assertEqual(len(statements), 1)
            self.assertEqual(statements[0].statement_type, StatementType.INSERT_INTO)
            self.assertEqual(statements[0].table_name, 'users')
            
        finally:
            os.unlink(temp_file)
    
    def test_parse_multiple_statements(self):
        """测试解析多个语句"""
        sql = """
        CREATE DATABASE test_db;
        
        USE test_db;
        
        CREATE TABLE users (
            id int PRIMARY KEY,
            name varchar(100)
        );
        
        INSERT INTO users (id, name) VALUES (1, 'Test');
        
        CREATE INDEX idx_name ON users (name);
        """
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.sql', delete=False) as f:
            f.write(sql)
            temp_file = f.name
        
        try:
            statements = self.parser.parse_file(temp_file)
            
            # 应该解析出多个语句
            self.assertGreater(len(statements), 1)
            
            # 检查语句类型
            types = [stmt.statement_type for stmt in statements]
            self.assertIn(StatementType.CREATE_DATABASE, types)
            self.assertIn(StatementType.CREATE_TABLE, types)
            self.assertIn(StatementType.INSERT_INTO, types)
            
        finally:
            os.unlink(temp_file)
    
    def test_get_table_names(self):
        """测试获取表名"""
        sql = """
        CREATE TABLE users (id int);
        CREATE TABLE orders (id int);
        INSERT INTO users VALUES (1);
        """
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.sql', delete=False) as f:
            f.write(sql)
            temp_file = f.name
        
        try:
            statements = self.parser.parse_file(temp_file)
            table_names = self.parser.get_table_names()
            
            self.assertIn('users', table_names)
            self.assertIn('orders', table_names)
            
        finally:
            os.unlink(temp_file)
    
    def test_preprocess_content(self):
        """测试内容预处理"""
        sql = """
        /* This is a comment */
        SET NAMES utf8;
        -- Another comment
        LOCK TABLES users WRITE;
        CREATE TABLE test (id int);
        UNLOCK TABLES;
        """
        
        processed = self.parser._preprocess_content(sql)
        
        # 注释和SET语句应该被移除
        self.assertNotIn('/*', processed)
        self.assertNotIn('SET NAMES', processed)
        self.assertNotIn('--', processed)
        self.assertNotIn('LOCK TABLES', processed)
        self.assertNotIn('UNLOCK TABLES', processed)
        
        # CREATE TABLE应该保留
        self.assertIn('CREATE TABLE', processed)


if __name__ == '__main__':
    unittest.main()
